package org.kalai.unifypay.servlet;

import java.io.IOException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.kalai.unifypay.Constant;
import org.kalai.unifypay.SessionManager;
import org.kalai.unifypay.bean.Bizcnf;
import org.kalai.unifypay.bean.Member;
import org.kalai.unifypay.bean.Transflow;
import org.kalai.unifypay.util.CommonUtil;
import org.kalai.unifypay.util.DataDao;
import org.kalai.unifypay.util.ProxyPayUtil;

import com.alibaba.fastjson.JSON;

@WebServlet(urlPatterns="/WXNotify")
public class WXNotify extends HttpServlet {
	private static final long serialVersionUID = -1527420512755124981L;
	private static final Logger logger = Logger.getLogger(WXNotify.class);
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		CommonUtil.responseObject(resp, Constant.ERROR_REQEST);
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			String merNo = request.getParameter("merNo");//商户号
			String tranxSN = request.getParameter("orderNo");//订单号
			String transAmt = request.getParameter("transAmt");//订单金额
			String orderDate = request.getParameter("orderDate");//订单日期
			String respCode = request.getParameter("respCode");//应答码
			String respDesc = request.getParameter("respDesc");//应答描述
			respCode = "0000".equals(respCode) ? "00" : respCode;
			boolean isok = "00".equals(respCode);
			logger.info(String.format("接收到异步通知[%s-%s-%s-%s]", tranxSN, transAmt, respCode, respDesc));
			if (tranxSN.startsWith("OR")) {//订单异步完成后异步通知
				Transflow transflow = DataDao.getInstance().getTransflow(tranxSN);
				if(transflow == null) {
					logger.error(String.format("交易信息不存在[%s,%s,%s,%s,%s,%s]", merNo, tranxSN, transAmt, orderDate, respCode, respDesc));
					CommonUtil.responseObject(response, "FAILED");//如果订单信息不存在  可能是异步通知先于同步返回  此时不予处理等待再次通知
					return;
				}
				if(transflow.getStatus() == 1){//未处理的订单才进行处理
					Member member = DataDao.getInstance().getMember(transflow.getMemberNo());
					if (member == null) throw new RuntimeException("商户信息不存在:"+transflow.getMemberNo());
					//更新交易表
					DataDao.getInstance().updateTransflow(tranxSN, transflow.getPayAccount(), Long.valueOf(transAmt), isok ? 2 : 3, respCode.toString(), respDesc.toString());
					String bizcode = transflow.getBizcode();
					Bizcnf bizcnf = DataDao.getInstance().getBizcnfByCode(bizcode);
					if(isok && bizcnf.getPattern() == 0){//D0交易成功后实时代付出去
						String settNo = CommonUtil.generSettNo();
						boolean flag = DataDao.getInstance().addSettlement(tranxSN, settNo, bizcode, member, transflow.getTransAmt() - transflow.getTransFee(), 1);
						if (flag) ProxyPayUtil.proxyPay(settNo, member, ((Double)(transflow.getTransAmt() * 100 - transflow.getTransFee() * 100)).longValue(), bizcode, true);
					}
					//异步通知账单系统
					CommonUtil.notifyTransFlow(transflow);
					//异步通知用户
					String url = transflow.getNotifyUrl();
					String partnerCode = transflow.getPartnerCode();
					String secret = DataDao.getInstance().getPartnerByCode(partnerCode).getPartnerSecret();
					if(url != null && !"".equals(url)) 
						CommonUtil.notifyMessage(url, partnerCode, secret, tranxSN, transflow.getOrderNo(), transflow.getTransAmt(), 
								respCode, respDesc);
					//websocket推送消息
					Map<String, Object> result = CommonUtil.createRespMap(respCode, respDesc);
					SessionManager.getInstance().broadcast(tranxSN, JSON.toJSONString(result));
				}
			} else if (tranxSN.startsWith("ST")) {//代付订单通知
				DataDao.getInstance().updateSettlement(tranxSN, respCode, respDesc, isok ? 4 : 5);
			}
			CommonUtil.responseObject(response, "SUCCESS");
		} catch (Exception e) {
			CommonUtil.responseObject(response, "SUCCESS");
			logger.error(e);
		}
	}
}
